/*
#ifndef _RSP_SERVER_SIDE
#error define _RSP_SERVER_SIDE
#endif
*/
#include "../bmanlib/world.h"
//#include "../rsp/s_room.h"
#include "../rsp/s_net.h"
#include "coid/comm/binstream/netstream.h"

////////////////////////////////////////////////////////////////////////////////
class bml_world : public rsp_world_controller
{
    World _SW;

public:
    

    virtual ushort get_version() const
    {
        return World::get_version();
    }

    ///External method that iterates over set of managed tiles and calls frame() on them
    virtual void iterate_tiles_frame()
    {
    }

    ///External method that iterates over set of managed tiles and calls diff() on them
    virtual void iterate_tiles_diff()
    {
    }


    virtual opcd allow_attach( const netAddress& addr, const uchar* rqdata, uint rqlen ) const
    {
        //if( _SW._gamestate != World::GS_BOOTING )
        //    return ersIMPROPER_STATE;
        if( get_total_players() >= World::MEN )
            return ersNO_MORE;
        return 0;
    }

    virtual opcd initialize_tiles()
    {
        _SW.init( get_frame_usec() );
        return 0;
    }

    virtual opcd attach_client( rsp_s_connector& rsps )
    {
        return 0;//_SW.rsp_attach(rsps);
    }

    virtual bool detach_client( rsp_s_connector& rsps )
    {
        //TODO: we should mark the disconnected state for possible reconnects
        return 0;//_SW.rsp_detach(rsps);
    }


    bml_world()
    {
        _SW.load_schemes();
    }
};

////////////////////////////////////////////////////////////////////////////////
class bml_net : public rsp_s_net
{
public:

    ///Create rsp_s_room_controller object
    virtual rsp_world_controller* create_world()
    {
        return new bml_world;
    }
};

////////////////////////////////////////////////////////////////////////////////
bml_net& get_server()
{
    static bml_net net;
    return net;
}

////////////////////////////////////////////////////////////////////////////////
int start_server( int argc, char *argv[] )
{
    netSubsystem::instance();
    get_server();

    if( argc>1 )
        TESTING_MODE = token(argv[1]).touint();
    else
        TESTING_MODE = 2;

    return 0;
}

void loop_server( void (*callback)(void) )
{
    get_server().server_process( callback );
}
